#import('dart:html');
#import('dart:json');

#source('Ball.dart');
#source('Balls.dart');
#source('Util.dart');

var IP='127.0.0.1';
var PORT=8080;
int INTERVAL_FRAME_RATE = 50;

class SampleClient {
  WebSocket ws;
  Balls balls;
  Ball ball;
  String _token = null;
  
  SampleClient() {
    balls = new Balls();
  }
  
  void run() {
    ws = new WebSocket("ws://$IP:$PORT/ws");
    ws.on.open.add((a) {
      print("open $a");
    });
    
    ws.on.close.add((c) {
      print("close $c");
    });
     
    ws.on.message.add((m) {
      var jdata = JSON.parse(m.data);
      String sender = jdata["sender"];
      // event triggered by ourself
      if (sender != null && sender == _token) {
        print("$_token skipping update " + m.data);
      }
      if (jdata["cmd"] == "token") { 
        _token = jdata["arg"];
        _init();
        return;
      } 
      double x = Math.parseDouble(jdata["x"]); 
      double y = Math.parseDouble(jdata["y"]); 
      double vx = Math.parseDouble(jdata["vx"]); 
      double vy = Math.parseDouble(jdata["vy"]); 
      double ax = Math.parseDouble(jdata["ax"]); 
      double ay = Math.parseDouble(jdata["ay"]); 
      int nr = Math.parseInt(jdata["nr"]); 
      Ball existingBall = balls.ballForNr(nr);
      if (jdata["cmd"] == "updateBall") { 
        if (existingBall == null) {
          Ball ball = new Ball(balls.root, x, y, nr);
          balls.balls.add(ball);
          print("$_token creating new ball " + m.data);
        } else {
          existingBall.x = x;
          existingBall.y = y;
          existingBall.vx = vx;
          existingBall.vy = vy;
          existingBall.ax = ax;
          existingBall.ay = ay;
          print("$_token updating ball " + m.data);
        }
      }
    });
  }

  _init() {
    _newBall();

    final double dx = 10;
    final double dy = 10;
    document.body.on.keyDown.add((KeyboardEvent e) {
      
      final int code = e.keyCode;
      
//      if (code == 13) { // Enter
//        _newBall();
//        e.stopPropagation();
//        return;
//      }      

//      else 
      
      // left arrow  
      if (code == 37) {
        ball.accelerate(-dx, 0);
        e.stopPropagation();
      }      
      // right arrow
      else if (code == 39) { 
        ball.accelerate(dx, 0);
        e.stopPropagation();
      }      
      // up arrow
      else if (code == 38) { 
        ball.accelerate(0, -dy);
        e.stopPropagation();
      }      
      // down arrow
      else if (code == 40) { 
        ball.accelerate(0, dy);
        e.stopPropagation();
      } else {
        ball.accelerate(0, 0);
      }
      _sendBallsToServer();

    });
    TimeoutHandler handler = () => _tick();
    window.setInterval(handler, INTERVAL_FRAME_RATE);

  }
  
 _newBall() {
   int nr = Math.parseInt(_token) % 7;
   ball = balls.add(200.0, 200.0, nr);
   _sendBallToServer(ball);
 }

 _sendBallToServer(Ball ball) {
  ws.send(JSON.stringify({"cmd": "updateBall", "sender": _token, "nr": ball.color.toString(), 
     "x": "${ball.x}", "y": "${ball.y}", "vx": "${ball.vx}", "vy": "${ball.vy}", "ax": "${ball.ax}", "ay": "${ball.ay}" }));
 }
 
_sendBallsToServer() {
  balls.balls.forEach(_sendBallToServer);
}

_tick() {
   balls.tick();
 }
}
 
 
void main() {
  new SampleClient().run();
}
